home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / CodeWarrior Lite / Metrowerks C⁄C++ Lite / Libraries / Runtime / Runtime 68K / CPlusLib68K.cp next >
Encoding:
Text File  |  1995-04-19  |  9.0 KB  |  269 lines  |  [TEXT/MMCC]

  1. /************************************************************************/
  2. /*    Project...:    Standard C++ Library                                    */
  3. /*    Name......:    CPlusLib.c                                                */
  4. /*    Purpose...:    C++ specific runtime functions                            */
  5. /*  Copyright.: ©Copyright 1993-95 by metrowerks inc                    */
  6. /************************************************************************/
  7.  
  8. #include <stdlib.h>
  9. #include <CPlusLib.h>
  10.  
  11. long            __ptmf_null[3];                //    a NULL pointer to member
  12.  
  13. /************************************************************************/
  14. /* Purpose..: Test if a pointer to function member is != 0                */
  15. /* Input....: pointer to function member                                */
  16. /* Return...: 0: is zero; 1: is not zero                                */
  17. /************************************************************************/
  18. asm long __ptmf_test(const PTMF *ptmf)
  19. {
  20.     move.l    4(sp),a0    //    ptr_to_function_member
  21.     tst.l    (a0)+        //    test if *ptr_to_function_member == { 0L,0L,0L }
  22.     bne.s    L9
  23.     tst.l    (a0)+
  24.     bne.s    L9
  25.     tst.l    (a0)+
  26.     bne.s    L9
  27.     moveq    #0,d0
  28.     rts
  29. L9:    moveq    #1,d0
  30.     rts
  31. }
  32.  
  33. /************************************************************************/
  34. /* Purpose..: Test if two pointers to function member are equal            */
  35. /* Input....: two pointers to function members                            */
  36. /* Return...: 1: *ptmf1!=*ptmf2; 0: *ptmf1==*ptmf2                        */
  37. /************************************************************************/
  38. asm long __ptmf_cmpr(const PTMF *ptmf1,const PTMF *ptmf2)
  39. {
  40.     move.l    4(sp),a0        //    *ptmf1 
  41.     move.l    8(sp),a1        //    *ptmf2
  42.     cmpm.l    (a0)+,(a1)+
  43.     bne.s    L9    
  44.     cmpm.l    (a0)+,(a1)+
  45.     bne.s    L9    
  46.     cmpm.l    (a0)+,(a1)+
  47.     bne.s    L9    
  48.     moveq    #0,d0
  49.     rts
  50. L9:    moveq    #1,d0
  51.     rts
  52. }
  53.  
  54. /************************************************************************/
  55. /* Purpose..: Call a member function through a pointer to member        */
  56. /* Input....: (a0: pointer to this if THIS_IN_A0!=0)                    */
  57. /* Input....: (a1: pointer to pointer to function member struct)        */
  58. /* Input....: (all other arguments on stack)                            */
  59. /* Return...: ---                                                        */
  60. /************************************************************************/
  61. asm void __ptmf_call(...)
  62. {
  63. #if !THIS_IN_A0
  64.     move.l    4(sp),a0                                            //    load this pointer into a0
  65.     add.l    struct(PTMF.this_delta)(a1),a0        //    adjust this pointer
  66.     move.l    a0,4(sp)                                            //    store new this pointer
  67. #else
  68.     add.l    struct(PTMF.this_delta)(a1),a0        //    adjust this pointer
  69. #endif
  70.     tst.l    struct(PTMF.vtbl_offset)(a1)
  71.     blt.s    directcall
  72.  
  73.     move.l    struct(PTMF.vtbl_offset)(a1),-(sp)
  74.     move.l    struct(PTMF.func_data.ventry_offset)(a1),-(sp)
  75.     move.l    a0,a1            //    load *this to a1
  76.     add.l    (sp)+,a1        //    add offset of vtableptr to a1
  77.     move.l    (a1),a1            //    load vtableptr to a1
  78.     add.l    (sp)+,a1        //    add vtable entry offset to a1
  79.     add.l    4(a1),a0        //    adjust adjust this pointer by vtable entry offset delta
  80. #if !THIS_IN_A0
  81.     move.l    a0,4(sp)        //    store new this pointer
  82. #endif
  83.     move.l    (a1),a1            //    get function address from vtable entry
  84.     jmp        (a1)
  85.  
  86. directcall:
  87.     move.l    struct(PTMF.func_data.func_addr)(a1),a1
  88.     jmp        (a1)
  89. }
  90.  
  91. /************************************************************************/
  92. /* Purpose..: Call a member function through a pointer to member        */
  93. /* Input....: (a0: pointer to this if THIS_IN_A0!=0)                    */
  94. /* Input....: (a1: pointer to pointer to function member struct)        */
  95. /* Input....: (all other arguments on stack)                            */
  96. /* Return...: ---                                                        */
  97. /************************************************************************/
  98. asm void __ptmf_scall(...)
  99. {
  100.     tst.l    struct(PTMF.vtbl_offset)(a1)
  101.     blt.s    directcall
  102.  
  103.     move.l    struct(PTMF.vtbl_offset)(a1),-(sp)
  104.     move.l    struct(PTMF.func_data.ventry_offset)(a1),-(sp)
  105. #if !THIS_IN_A0
  106.     move.l    a0,a1            //    load this pointer into a1
  107. #else
  108.     move.l    4+8(sp),a1        //    load this pointer into a1
  109. #endif
  110.     add.l    (sp)+,a1        //    add offset of vtableptr to a1
  111.     move.l    (a1),a1            //    load vtableptr to a1
  112.     add.l    (sp)+,a1        //    add vtable entry offset to a1
  113.     move.l    (a1),a1            //    get function address from vtable entry
  114.     jmp        (a1)
  115.  
  116. directcall:
  117.     move.l    struct(PTMF.func_data.func_addr)(a1),a1
  118.     jmp        (a1)
  119. }
  120.  
  121. /************************************************************************/
  122. /* Purpose..: This function will copy/cast a pointer to func member        */
  123. /* Input....: offset delta to apply    to pointer to function member        */
  124. /* Input....: pointer to original pointer to function member            */
  125. /* Input....: pointer to destiniation pointer to function member        */
  126. /* Return...: pointer to destiniation pointer to function member        */
  127. /************************************************************************/
  128. PTMF *__ptmf_cast(long offset,const PTMF *ptmfrom,PTMF *ptmto)
  129. {
  130.     ptmto->this_delta=ptmfrom->this_delta+offset;
  131.  
  132.     if(((PTMF *)ptmfrom)->vtbl_offset>=0L)
  133.     {    //    virtual function pointer
  134.         ((PTMF *)ptmto)->vtbl_offset=((PTMF *)ptmfrom)->vtbl_offset+offset;
  135.         ((PTMF *)ptmto)->func_data.ventry_offset=((PTMF *)ptmfrom)->func_data.ventry_offset;
  136.     }
  137.     else
  138.     {    //    nonvirtual function pointer
  139.         ((PTMF *)ptmto)->vtbl_offset=-1L;
  140.         ((PTMF *)ptmto)->func_data.func_addr=((PTMF *)ptmfrom)->func_data.func_addr;
  141.     }
  142.     return(ptmto);
  143. }
  144.  
  145. /************************************************************************/
  146. /*    Purpose..:     Copy data                                                */
  147. /*    Input....:    pointer to destination (can be 0L: no copy)                */
  148. /*    Input....:    pointer to source                                        */
  149. /*    Input....:    number of bytes to copy                                    */
  150. /*    Return...:    pointer to destination (or 0L)                            */
  151. /************************************************************************/
  152. void *__copy(char *to,char *from,size_t size)
  153. {
  154.     char *f,*t;
  155.  
  156.     if(to) for(f=(char *)from,t=(char *)to; size>0; size--) *t++=*f++;
  157.     return to;
  158. }
  159.  
  160. /************************************************************************/
  161. /*    Purpose..:     Initialize an array of objects                            */
  162. /*    Input....:    pointer to allocated memory (+8 bytes) (0L: error)        */
  163. /*    Input....:    pointer to default constructor function    (if any)        */
  164. /*    Input....:    size of one object                                        */
  165. /*    Input....:    number of objects                                        */
  166. /*    Return...:    pointer to first object                                    */
  167. /************************************************************************/
  168. void *__init_arr(void *memptr,ConstructorDestructor constructor,size_t object_size,size_t nobjects)
  169. {
  170.     char    *ptr;
  171.  
  172. //    Theory of operation:
  173. //
  174. //    Allocate space for: two size_t objects and nobjects*object_size objects;
  175. //    Store number of allocated object and size of one object at the beginnig of the allocated block;
  176. //    Call constructor (if any) to initialize object memory;
  177. //    return pointer to first object;
  178.  
  179.     if((ptr=(char *)memptr)!=0L)
  180.     {
  181.         *(size_t *)ptr=object_size;
  182.         *(size_t *)(ptr+sizeof(size_t))=nobjects;
  183.         ptr+=sizeof(size_t)*2;
  184.  
  185.         if(constructor)
  186.         {
  187.             char    *p;
  188.             size_t    i;
  189.  
  190.             for(i=0,p=ptr; i<nobjects; i++,p+=object_size) constructor(p,1);
  191.         }
  192.     }
  193.     return(ptr);
  194. }
  195.  
  196. /************************************************************************/
  197. /*    Purpose..:     Construct an array of objects                            */
  198. /*    Input....:    pointer to default constructor function    (if any)        */
  199. /*    Input....:    size of one object                                        */
  200. /*    Input....:    number of objects                                        */
  201. /*    Return...:    pointer to first object                                    */
  202. /************************************************************************/
  203. void *__new_arr(ConstructorDestructor constructor,size_t object_size,size_t nobjects)
  204. {
  205.     char    *ptr;
  206.  
  207. //    Theory of operation:
  208. //
  209. //    Allocate space for: two size_t objects and nobjects*object_size objects;
  210. //    Store number of allocated object and size of one object at the begining of the allocated block;
  211. //    Call constructor (if any) to initialize object memory;
  212. //    return pointer to first object;
  213.  
  214.     if((ptr=(char *)::operator new(2*sizeof(size_t)+object_size*nobjects))!=0L)
  215.     {
  216.         *(size_t *)ptr=object_size;
  217.         *(size_t *)(ptr+sizeof(size_t))=nobjects;
  218.         ptr+=sizeof(size_t)*2;
  219.         if(constructor)
  220.         {
  221.             char    *p;
  222.             size_t    i;
  223.  
  224.             for(i=0,p=ptr; i<nobjects; i++,p+=object_size) constructor(p,1);
  225.         }
  226.     }
  227.     return(ptr);
  228. }
  229.  
  230. /************************************************************************/
  231. /*    Purpose..:     Delete an array of objects                                */
  232. /*    Input....:    pointer to first object    (can be 0L)                        */
  233. /*    Input....:    pointer to destructor function (if any)                    */
  234. /*    Return...:    ---                                                        */
  235. /************************************************************************/
  236. void __del_arr(void *memptr,ConstructorDestructor destructor)
  237. {
  238.     if(memptr)
  239.     {
  240.         if(destructor)
  241.         {
  242.             size_t    i,objects,objectsize;
  243.             char    *p;
  244.  
  245.             objectsize=*(size_t *)((char *)memptr-2*sizeof(size_t));
  246.             objects=*(size_t *)((char *)memptr-sizeof(size_t));
  247.             p=(char *)memptr+objectsize*objects;
  248.             for(i=0; i<objects; i++)
  249.             {
  250.                 p-=objectsize; destructor(p,-1);
  251.             }
  252.         }
  253.         ::delete ((char *)memptr-2*sizeof(size_t));
  254.     }
  255. }
  256.  
  257. /************************************************************************/
  258. /*    Purpose..:     Construct/destruct an array of objects                    */
  259. /*    Input....:    pointer to memory location                                */
  260. /*    Input....:    pointer to constructor/destructor function                */
  261. /*    Input....:    size of object                                            */
  262. /*    Input....:    number of objects                                        */
  263. /*    Return...:    ---                                                        */
  264. /************************************************************************/
  265. void __dc_arr(void *mem,ConstructorDestructor con_des,short object_size,short objects)
  266. {
  267.     while(objects-->0) { con_des(mem,-1); *((char **)&mem)+=object_size; }
  268. }
  269.